const redisClient = require('../config/redis_config');
const crypto = require('crypto');

class SessionManager {
    constructor() {
        this.redisClient = redisClient;
    }

    // 生成随机令牌
    generateToken(userId, ip) {
        // 使用时间戳和随机数增加随机性
        const timestamp = Date.now();
        const randomBytes = crypto.randomBytes(16).toString('hex');
        const input = `${userId}-${ip}-${timestamp}-${randomBytes}`;
        return crypto.createHash('sha256').update(input).digest('hex');
    }

    // 创建新会话
    async createSession(userId, ip) {
        const token = this.generateToken(userId, ip);
        const sessionKey = `session:${token}`;
        const sessionData = {
            userId,
            ip,
            createdAt: Date.now()
        }
		
        try {
			// 删除这个用户之前的所有会话
			const oldSessions = await this.getTokenByUserAndIp(userId, ip);
			if (oldSessions) {
				await this.invalidateSession(oldSessions);
			}

            // 设置会话数据，过期时间设为24小时
            await this.redisClient.setEx(sessionKey, 24 * 60 * 60, JSON.stringify(sessionData));
            return token;
        } catch (error) {
            console.error('创建会话失败:', error);
            throw new Error('创建会话失败');
        }
    }

    // 验证会话
    async validateSession(token, ip) {
        const sessionKey = `session:${token}`;
        try {
            const sessionData = await this.redisClient.get(sessionKey);
            if (!sessionData) {
                return false;
            }

            const session = JSON.parse(sessionData);
            // 验证IP是否匹配
            if (session.ip !== ip) {
                return false;
            }

            // 更新会话过期时间
            await this.redisClient.expire(sessionKey, 24 * 60 * 60);
            return session;
        } catch (error) {
            console.error('验证会话失败:', error);
            return false;
        }
    }

    // 注销会话
    async invalidateSession(token) {
        const sessionKey = `session:${token}`;
        try {
            await this.redisClient.del(sessionKey);
            return true;
        } catch (error) {
            console.error('注销会话失败:', error);
            return false;
        }
    }

    // 获取会话信息
    async getSession(token) {
        const sessionKey = `session:${token}`;
        try {
            const sessionData = await this.redisClient.get(sessionKey);
            return sessionData ? JSON.parse(sessionData) : null;
        } catch (error) {
            console.error('获取会话信息失败:', error);
            return null;
        }
    }

    // 获取所有会话
    async getAllSessions() {
        try {
            // 获取所有以 'session:' 开头的键
            const keys = await this.redisClient.keys('session:*');
            const sessions = [];

            // 获取每个会话的详细信息
            for (const key of keys) {
                const sessionData = await this.redisClient.get(key);
                if (sessionData) {
                    const session = JSON.parse(sessionData);
                    // 获取剩余过期时间
                    const ttl = await this.redisClient.ttl(key);
                    sessions.push({
                        token: key.split(':')[1],
                        ...session,
                        expiresIn: ttl
                    });
                }
            }

            return sessions;
        } catch (error) {
            console.error('获取所有会话失败:', error);
            return [];
        }
    }

    // 通过用户ID和IP查询token
    async getTokenByUserAndIp(userId, ip) {
        try {
            // 获取所有会话
            const sessions = await this.getAllSessions();
            
            // 查找匹配的会话
            const matchingSession = sessions.find(session => 
                session.userId === userId && session.ip === ip
            );

            return matchingSession ? matchingSession.token : null;
        } catch (error) {
            console.error('查询token失败:', error);
            return null;
        }
    }

    // 通过用户ID查询所有token
    async getTokensByUserId(userId) {
        try {
            const sessions = await this.getAllSessions();
            return sessions
                .filter(session => session.userId === userId)
                .map(session => ({
                    token: session.token,
                    ip: session.ip,
                    createdAt: session.createdAt,
                    expiresIn: session.expiresIn
                }));
        } catch (error) {
            console.error('查询用户token失败:', error);
            return [];
        }
    }

    // 通过IP查询所有token
    async getTokensByIp(ip) {
        try {
            const sessions = await this.getAllSessions();
            return sessions
                .filter(session => session.ip === ip)
                .map(session => ({
                    token: session.token,
                    userId: session.userId,
                    createdAt: session.createdAt,
                    expiresIn: session.expiresIn
                }));
        } catch (error) {
            console.error('查询IP token失败:', error);
            return [];
        }
    }
}

module.exports = new SessionManager(); 